package cn.silver.module.authority.domain;

import cn.silver.framework.core.enums.SystemStatusEnums;
import cn.silver.framework.core.utils.StringUtils;
import cn.silver.framework.encrypt.utils.EncryptUtils;
import cn.silver.framework.satoken.enums.DeviceTypeEnums;
import cn.silver.framework.mybatis.annotation.Table;
import cn.silver.framework.mybatis.annotation.TableField;
import cn.silver.framework.mybatis.enums.SearchEnums;
import cn.silver.framework.mybatis.domain.BusEntity;
import cn.silver.framework.satoken.enums.GrantTypeEnums;
import cn.silver.framework.web.enums.CaptchaTypeEnums;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.io.Serial;
import java.util.Map;

/**
 * 授权管理对象 sys_client
 *
 * @author Silver Zhou
 */
@Data
@NoArgsConstructor
@Table(name = "sys_client")
@EqualsAndHashCode(callSuper = true)
@Schema(name = "SysClient", title = "客户端对象", description = "客户端授权管理对象")
public class SysClient extends BusEntity {

    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * 注册入口
     */
    @Schema(title = "是否开放注册入口")
    private Boolean register;

    /**
     * 验证码类型
     */
    @Schema(title = "验证码类型")
    private String captcha;

    /**
     * 访问地址
     */
    @Schema(title = "访问地址")
    private String webUrl;

    /**
     * 授权类型
     */
    @Schema(title = "授权类型")
    @TableField(name = "grant_type", searchType = SearchEnums.LIKE)
    private String grantType;

    /**
     * 设备类型
     */
    @Schema(title = "设备类型")
    @TableField(name = "device_type", searchType = SearchEnums.EQ)
    private String deviceType;

    /**
     * token活跃超时时间
     */
    @Schema(title = "活跃超时时间")
    private Long activeTimeout;

    /**
     * token固定超时时间
     */
    @Schema(title = "固定超时时间")
    private Long timeout;

    /**
     * 客户端秘钥
     */
    @Schema(title = "客户端秘钥")
    private String secret;

    /**
     * 客户端公钥
     */
    @Schema(title = "客户端公钥")
    private String publicKey;
    /**
     * 客户端私钥
     */
    @Schema(title = "客户端私钥")
    private String privateKey;
    /**
     * 客户端签名
     */
    @Schema(title = "客户端签名")
    private String signatrue;

    /**
     * 状态
     */
    @Schema(title = "状态")
    @TableField(name = "status", searchType = SearchEnums.EQ)
    private String status;

    public static SysClient getInstant(DeviceTypeEnums device) {
        SysClient client = new SysClient();
        client.setCode(device.getCode());
        client.setName(device.getName());
        client.setStatus(SystemStatusEnums.NORMAL.getCode());
        client.setGrantType(GrantTypeEnums.AUTH_PASSWORD.getCode());
        client.setDeviceType(device.getCode());
        client.setCaptcha(CaptchaTypeEnums.NONE.getCode());
        client.setRegister(Boolean.TRUE);
        return client;
    }

    @Override
    public void preInsert() {
        super.preInsert();
        if (StringUtils.isBlank(this.grantType)) {
            this.grantType = GrantTypeEnums.AUTH_PASSWORD.getCode();
        }
        this.checkSecret();
    }

    @Override
    public void preUpdate() {
        super.preUpdate();
        this.checkSecret();
    }

    private void checkSecret() {
        if (StringUtils.isBlank(this.getSecret())) {
            this.setSecret(EncryptUtils.generateSecret(32));
        }
        if (StringUtils.isBlank(this.getPublicKey()) || StringUtils.isBlank(this.getPrivateKey())) {
            Map<String, String> keys = EncryptUtils.generateRsaKey();
            this.setPublicKey(keys.get(EncryptUtils.PUBLIC_KEY));
            this.setPrivateKey(keys.get(EncryptUtils.PRIVATE_KEY));
        }
        if (StringUtils.isBlank(this.getSignatrue())) {
            this.setSignatrue(EncryptUtils.signature(256, this.getCode() + "#" + this.getName()));
        }
    }
}
